//
//  LYQStatusViewModel.swift
//  SwiftWeibo
//
//  Created by 刘英群 on 2017/2/8.
//  Copyright © 2017年 刘英群. All rights reserved.
//

import Foundation

// 单条微博的视图模型

/*
 如果没有任何父类，如果希望在开发时调试，输出调试信息，需要
 1.遵守CustomStringConvertible
 2.实现 description 计算型属性
 
 关于表格的性能优化
 
 - 尽量少计算， 所有需要的素材提前计算好
 - 空间上不要设置圆角半径，所有图像渲染属性都要注意
 - 不要动态创建控件，所有需要的控件，都要提前创建好， 在显示的时候，根据数据隐藏、显示
 - cell 中控件的层次越少越好，数量越少越好
 */
class LYQStatusViewModel: CustomStringConvertible {
    
    // 微博模型
    var status:LYQStatus
    
    // 会员图标 - 存储型属性（用内存换cpu）
    var memberIcon: UIImage?
    
    // 认证图标 - 1没有认证 0认证用户 2，3，4企业认证 220：达人
    var vipIcon: UIImage?
    
    // 转发文字
    var retweetedStr: String?
    // 评论文字
    var commentStr: String?
    // 点赞文字
    var likeStr: String?
    
    //配图视图大小
    var pictureViewSize = CGSize()
    
    // 如果是被转发微博，原创微博一定没有图
    var picURLs: [LYQStatusPicture]? {
        // 如果有被转发的微博，返回被转发微博的配图
        // 如果没有被转发的微博，返回原创微博的配图
        // 如果都没有 返回nil
        return status.retweeted_status?.pic_urls ?? status.pic_urls
    }
    
    // 被转发微博的文字
    var retweetedText: String?
    
    var rowHeight: CGFloat = 0
    
    // 构造函数
    // parameter model：微博模型
    // returns：微博的视图模型
    init(model: LYQStatus) {
        
        self.status = model
        
        // 会员等级 0-6
        guard let mbrank = model.user?.mbrank else {
            
            return
        }
        
        if mbrank > 0 && mbrank < 7{
            
            let imageName = "common_icon_membership_level\(model.user?.mbrank ?? 1)"
            
            memberIcon = UIImage(named: imageName)
        }
        
        // 认证图标
        switch model.user?.verified_type ?? -1 {
        case 0:
            vipIcon = UIImage(named: "avatar_vip")
        case 2, 3, 5:
            vipIcon = UIImage(named: "avatar_enterprise_vip")
        case 220:
            vipIcon = UIImage(named: "avatar_grassroot")
        default:
            break
        }
        
        // 设置底部计数字符串
        retweetedStr = countString(count: model.reposts_count, defaultStr: "转发")
        commentStr = countString(count: model.comments_count, defaultStr: "评论")
        likeStr = countString(count: model.attitudes_count, defaultStr: "赞")
        
        // 计算配图视图的大小 （有原创的就计算原创的，有转发的就计算转发的）
        pictureViewSize = calcPictureViewSize(count: picURLs?.count)
        
        // 设置被转发微博的文字
        
        retweetedText = "@" + (status.retweeted_status?.user?.screen_name ?? " ") + ":" + (status.retweeted_status?.text ?? " ")
        
        // 计算行高
       updateRowHeight()
    
    }
    
    
    var description: String {
        
        return status.description
    }
    
    
    /// 根据当前的视图模型内容计算行高
    func updateRowHeight() {
    
        //原创微博
        //被转发微博
        
        let margin: CGFloat = 12
        let iconHeight: CGFloat = 34
        let toolbarHeight: CGFloat = 35
        
        var height:CGFloat = 0
        
        let viewSize = CGSize(width: UIScreen.cz_screenWidth() - 2 * margin, height: CGFloat( MAXFLOAT))
        let originalFont = UIFont.systemFont(ofSize: 15)
        let retweetedFont = UIFont.systemFont(ofSize: 14)
        
        // 1.计算顶部位置
        height = 2 * margin + iconHeight + margin
        
        // 2,正文高度
        if let text = status.text {
            
            /*
             四个参数
             1.预测尺寸，宽度固定，高度尽量大
             2.选项，换行文本，统一使用usesLineFragmentOrigin
             3.attributes: 指定字体字典
             */
            height += (text as NSString).boundingRect(with: viewSize,
                                            options: [.usesLineFragmentOrigin],
                                            attributes: [NSFontAttributeName: originalFont],context: nil).height
        }
        
        //3. 判断是否转发微博
        if status.retweeted_status != nil {
            
            height += 2 * margin
            
            //转发文本的高度 - 一定用 retweetedText， 拼接了@用户名: 微博文字
            if let text = retweetedText {
                
                height += (text as NSString).boundingRect(with: viewSize,
                                                          options: [.usesLineFragmentOrigin],
                                                          attributes: [NSFontAttributeName: retweetedFont],context: nil).height
            }
        }
        
        // 4.配图视图
        height += pictureViewSize.height
        
        height += margin
        
        // 5.底部工具栏
        height += toolbarHeight
        
        // 6.使用属性记录
        rowHeight = height
    }
    
    
    /// 使用单个图像，更新配图视图的大小
    ///
    /// - Parameter image: 网络缓存的单张图像
    func updateSingleImageSize(image: UIImage){
        
        var size = image.size
        
        //过宽图像处理
        let maxWidth: CGFloat = 300
        let minWidth: CGFloat = 40
        
        if size.width > maxWidth {
            //设置最大宽度
            size.width = maxWidth
            //等比例调整高度
            size.height = size.width * image.size.height / image.size.width
        }
        
        //过窄图像处理
        if size.width < minWidth {
            
            size.width = minWidth
            size.height = size.width * image.size.height / image.size.width / 4
        }
        
        // 注意 ：尺寸需要增加顶部12个点，便于布局
        size.height += LYQStatusPictureViewOutterMargin
        
        //重新设置配图视图大小
        pictureViewSize = size
        
        // 更新行高
        updateRowHeight()
    }
    
    
    /// 计算指定数量的图片对应的配图视图的大小
    ///
    /// - Parameter count: 配图数量
    /// - Returns: 配图视图的大小
    fileprivate func calcPictureViewSize(count: Int?) -> CGSize {

        if count == 0 || count == nil {
            
            return CGSize()
        }
       
        //2.计算高度
        // 2.1 根据count知道行数 1-9
        /*
            1 2 3 = 0 1 2 / 3 = 0 + 1 = 1
            4 5 6 = 3 4 5 / 3 = 1 + 1 = 2
            7 8 9 = 6 7 8 / 3 = 2 + 1 = 3
         */
        let row = (count! - 1) / 3 + 1
        
        // 2.2 根据行数算高度
        var height = LYQStatusPictureViewOutterMargin
        height += CGFloat(row) * LYQStatusPictureItemWidth
        height += CGFloat(row - 1) * LYQStatusPictureViewInnerMargin
        
        return CGSize(width: LYQStatusPictureViewWidth, height: height)
    }
    
    
    /// 给定一个数字，返回对应的描述结果
    ///
    /// - Parameters:
    ///   - count: 数字
    ///   - defaultStr: 默认字符串， 转发，评论， 赞
    /// - Returns: 描述结果
    fileprivate func countString(count: Int, defaultStr: String) -> String {
        
        if count == 0 {
            return defaultStr
        }
        
        if count < 10000 {
            return count.description
        }
        
        return String(format: "%.02f 万", Double(count)/10000)
    }
}
